home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 4 / BBS in a Box - Macintosh - Volume IV (January 1992) (BBS in a Box).iso / Files / Prog / B-C / COMPARE / COMPARE
Encoding:
Text File  |  1987-05-26  |  9.0 KB  |  241 lines  |  [MSBA/MSBA]

  1. 10 REM File Comparison Program.   Copyright 1984 John W. Baxter.
  2. 40 REM Input:  Two files, which can be processed by BASIC as text files.
  3. 50 REM Output:  A listing of the differences, on a line-by-line basis, 
  4. 60 REM              between the input files.  
  5. 70 REM The program attempts to handle cases in which extra lines 
  6. 80 REM exist in one of the files, by searching both files until equal lines
  7. 90 REM are discovered.
  8. 100 GOTO 1000
  9. 500 REM Get next line from file IFILE.
  10. 510 IF IGET(IFILE) THEN 600
  11. 520   LINE INPUT #IFILE, TNEXT(IFILE)
  12. 530  GOTO 630
  13. 600 TNEXT(IFILE)=T(IFILE, FIRST(IFILE))
  14. 602 T(IFILE, FIRST(IFILE))=""
  15. 610 FIRST(IFILE)=FIRST(IFILE)+1
  16. 620 IF FIRST(IFILE)<=LIMIT(IFILE) THEN 630
  17. 622   IGET(IFILE)=0: FIRST(IFILE)=0: LIMIT(IFILE)=0
  18. 630 COUNT(IFILE)=COUNT(IFILE)+1
  19. 640 RETURN
  20. 700 REM Print a line TPRINT, with line number LINENO.  
  21. 702 FOR C=1 TO LEN(TPRINT)
  22. 704   IF MID$(TPRINT, C, 1) < " " THEN MID$(TPRINT, C, 1) = TCONTROL
  23. 706   NEXT
  24. 710 PRINT #LFILE, USING "#,###  &"; LINENO, TPRINT
  25. 720 RETURN
  26. 730 REM Enhance for control chars & special cases.
  27. 1000 CLS
  28. 1002 CLEAR ,24000
  29. 1010 PRINT: PRINT "Text file compare.   Copyright "; CHR$(169);
  30. 1012 PRINT "1984  John W. Baxter"
  31. 1020 PRINT"Version 1.2"; CHR$(167); "  Last updated June 14, 1984 at 2115"
  32. 1030 REM Watch out for the following!
  33. 1040 DEFINT I-K: DEFSTR T
  34. 1042 OPTION BASE 1
  35. 1050 GOSUB 50000: REM Variable definitions
  36. 1060 GOSUB 40000: REM User input routine (file names, parameters)
  37. 1068 PRINT #LFILE,
  38. 1070 PRINT #LFILE, "Compare "; TNAME(1); " and "; TNAME(2); 
  39. 1080 PRINT #LFILE, " on "; DATE$; " at "; TIME$
  40. 1100 REM Files are in synch
  41. 1110 WHILE (NOT EOF(1)) AND (NOT EOF(2))
  42. 1120   FOR IFILE=1 TO 2: GOSUB 500: NEXT
  43. 1130   IF TNEXT(1)<>TNEXT(2) THEN GOSUB 2000
  44. 1140   WEND
  45. 1150 FOR IFILE=1 TO 2
  46. 1160   IF NOT EOF(IFILE) THEN GOSUB 3000: REM Report extra lines.
  47. 1170   NEXT
  48. 1180 CLOSE
  49. 1190 PRINT: PRINT "Compare completed.  ";
  50. 1192 IF ISDIF THEN PRINT "Check differences."
  51. 1200 IF ISSCREEN AND ISDIF THEN PRINT: PRINT
  52. 1210 END
  53. 2000 REM Process file difference other than extra text at end
  54. 2010 FOR I=1 TO 2
  55. 2020   BOTTOM(I)=COUNT(I)
  56. 2030   T(I,1)=TNEXT(I)
  57. 2040   LAST(I)=1
  58. 2050   NEXT
  59. 2060 REM UNTIL Resynchronized or out of space in arrays
  60. 2070 IFILE=1: JFILE=2
  61. 2080 REM REPEAT
  62. 2090   IF EOF (IFILE) THEN 2100
  63. 2092     GOSUB 500
  64. 2094     LAST(IFILE)=LAST(IFILE)+1
  65. 2096     T(IFILE, LAST(IFILE))=TNEXT(IFILE)
  66. 2100   REM Single-line resynch test only.
  67. 2110   I=1
  68. 2120     IF TNEXT(IFILE)=T(JFILE,I) THEN 2200
  69. 2130     I=I+1
  70. 2140     IF I<= LAST(JFILE) THEN 2120
  71. 2150   IF EOF(IFILE) AND EOF (JFILE) THEN 2800
  72. 2160   IF LAST(IFILE)=MAXLINES THEN 2500
  73. 2170   SWAP IFILE,JFILE
  74. 2180   GOTO 2090: REM UNTIL Resynchronized {or out of array space}
  75. 2200 REM Resynchronized by matching line.
  76. 2210 IF I=1 THEN 2600: REM Extra text between lines.
  77. 2212 ISDIF=1
  78. 2220 PRINT #LFILE,: PRINT #LFILE, "Difference:"
  79. 2222 PRINT #LFILE, "Lines from "; TNAME(IFILE); ":"
  80. 2230 FOR J=1 TO LAST(IFILE)-1
  81. 2240   LINENO=BOTTOM(IFILE)+J-1: TPRINT= T(IFILE,J): GOSUB 700
  82. 2242   T(IFILE, J)=""
  83. 2250   NEXT
  84. 2260 PRINT #LFILE, "Lines from "; TNAME(JFILE); ":"
  85. 2270 FOR J=1 TO I-1
  86. 2280   LINENO=BOTTOM(JFILE)+J-1: TPRINT= T(JFILE,J): GOSUB 700
  87. 2282   T(JFILE, J)=""
  88. 2290   NEXT
  89. 2300 IF I=LAST(JFILE) THEN RETURN
  90. 2310 COUNT(JFILE)=BOTTOM(JFILE)+I-1: BOTTOM(JFILE)=COUNT(JFILE)+1
  91. 2320 FOR J=1 TO LAST(JFILE)-I
  92. 2330   T(JFILE,J)=T(JFILE,I+J)
  93. 2340   T(JFILE,I+J)=""
  94. 2350   NEXT
  95. 2358 IF FIRST(JFILE)=0 THEN 2410
  96. 2360 WHILE FIRST(JFILE)<=LIMIT(JFILE)
  97. 2370   T(JFILE,J)=T(JFILE,FIRST(JFILE))
  98. 2380   T(JFILE,FIRST(JFILE))=""
  99. 2390   J=J+1: FIRST(JFILE)=FIRST(JFILE)+1
  100. 2400   WEND
  101. 2410 LIMIT(JFILE)=J-1: FIRST(JFILE)=1
  102. 2420 IGET(JFILE)=1
  103. 2430 RETURN
  104. 2500 REM Too much difference to resynchronize.  Temporary: Give up!
  105. 2510 PRINT #LFILE, : PRINT #LFILE, "Files are too different to report!"
  106. 2520 ISDIF=1
  107. 2530 GOTO 1180
  108. 2600 REM Report extra text in IFILE between lines of JFILE
  109. 2610 PRINT #LFILE, : PRINT #LFILE, "Extra text on "; TNAME(IFILE);
  110. 2612 PRINT #LFILE, ", between lines"; BOTTOM(JFILE)-1;
  111. 2613 PRINT #LFILE, "and"; BOTTOM(JFILE);
  112. 2614 PRINT #LFILE, "of "; TNAME(JFILE)
  113. 2618 ISDIF=1
  114. 2620 FOR I=1 TO LAST(IFILE)-1
  115. 2630   LINENO=BOTTOM(IFILE)+I-1: TPRINT=T(IFILE,I): GOSUB 700
  116. 2640   T(IFILE,I)=""
  117. 2650   NEXT
  118. 2680 FOR J=1 TO LAST(JFILE)-1
  119. 2690   T(JFILE,J)=T(JFILE,J+1)
  120. 2700   NEXT
  121. 2710 T(JFILE,J)=""
  122. 2720 WHILE (FIRST(JFILE)>0) AND (FIRST(JFILE)<=LIMIT(JFILE))
  123. 2730   T(JFILE,J)=T(JFILE,FIRST(JFILE)): T(JFILE, FIRST(JFILE))=""
  124. 2740   J=J+1: FIRST(JFILE)=FIRST(JFILE)+1
  125. 2750   WEND
  126. 2760 LIMIT(JFILE)=J-1
  127. 2780 IF LIMIT(JFILE)>0 THEN 2786
  128. 2782   FIRST(JFILE)=0: IGET(JFILE)=0: GOTO 2790
  129. 2786   FIRST(JFILE)=1: IGET(JFILE)=1
  130. 2787   COUNT(JFILE)=BOTTOM(JFILE)
  131. 2788   BOTTOM(JFILE)=COUNT(JFILE)+1
  132. 2790 RETURN
  133. 2800 REM Both files have End of File, and a resynchronize is in progress.
  134. 2810 PRINT #LFILE,: PRINT #LFILE, "Difference:  non-matching ";
  135. 2812 PRINT #LFILE, "lines at ends of the files."
  136. 2820 ISDIF=1
  137. 2830 FOR IFILE=1 TO 2
  138. 2840   PRINT #LFILE, "Lines from "; TNAME(IFILE); ":"
  139. 2850   FOR I=1 TO LAST(IFILE)
  140. 2860     LINENO=BOTTOM(IFILE)+I-1: TPRINT=T(IFILE,I): GOSUB 700
  141. 2870     T(IFILE,I)=""
  142. 2880     NEXT
  143. 2890   IF IFILE=1 THEN PRINT#LFILE,
  144. 2900   NEXT
  145. 2910 RETURN
  146. 3000 REM Display extra text on end of an input file.
  147. 3010 ISDIF=1
  148. 3020 PRINT #LFILE,
  149. 3022 PRINT #LFILE, "Extra text on end of file "; TNAME(IFILE); ":"
  150. 3030 WHILE NOT EOF(IFILE)
  151. 3040   GOSUB 500
  152. 3050   LINENO=COUNT(IFILE): TPRINT= TNEXT(IFILE): GOSUB 700
  153. 3060   WEND
  154. 3070 RETURN
  155. 40000 REM Temporary user interaction.  Hopefully, to be replaced by a
  156. 40010 REM    pseudo-dialog box.
  157. 40020 IFILE=1
  158. 40030 GOSUB 41000: REM get file name for file 1.
  159. 40040 IFILE=2
  160. 40050 GOSUB 41000: REM Get file name for file 2.
  161. 40060 GOSUB 42000: REM Get other user input
  162. 40070 FOR I=1 TO 2
  163. 40080   ON ERROR GOTO 40200
  164. 40090   OPEN TNAME(I) FOR INPUT AS #I
  165. 40100   ON ERROR GOTO 0
  166. 40110   NEXT
  167. 40120 ON ERROR GOTO 40300
  168. 40130 OPEN TOUT FOR OUTPUT AS #LFILE
  169. 40140 ON ERROR GOTO 0
  170. 40148 GOSUB 40400: REM Determine whether output is SCRN:
  171. 40150 IF ISSCREEN THEN WIDTH#LFILE, 60 ELSE WIDTH#LFILE,79
  172. 40160 RETURN
  173. 40200 REM Error routine for opening input file
  174. 40210 IF ERL<>40090 THEN ON ERROR GOTO 0: REM Let BASIC handle it. 
  175. 40220 IF ERR<>53 THEN ON ERROR GOTO 0: REM Let BASIC handle it.
  176. 40230 IFILE=I
  177. 40240 BEEP: PRINT: PRINT "File "; TNAME(IFILE); " not found."
  178. 40250 LINE INPUT "Re-enter file name:  "; TNAME(IFILE)
  179. 40260 RESUME 40090
  180. 40300 REM Error routine for opening output file
  181. 40310 IF ERL<>40130 THEN ON ERROR GOTO 0: REM Let BASIC handle it.
  182. 40320 BEEP: PRINT: PRINT "Cannot open "; TOUT; " as output."
  183. 40330 LINE INPUT "Re-enter file or device name:  "; TOUT
  184. 40340 RESUME 40130
  185. 40400 FOR I=1 TO LEN(TOUT)
  186. 40410   T=MID$(TOUT, I, 1)
  187. 40420   IF (T>="a") AND (T<="z") THEN MID$(TOUT, I, 1)= CHR$(ASC(T)-32)
  188. 40430   NEXT
  189. 40440 ISSCREEN = (TOUT="SCRN:")
  190. 40442 IF ISSCREEN THEN WIDTH #LFILE, 60 ELSE WIDTH #LFILE, 79
  191. 40444 IF ISSCREEN THEN TCONTROL=CHR$(165) ELSE TCONTROL = "~"
  192. 40450 RETURN
  193. 41000 REM Routine to input an input file name
  194. 41010 PRINT "Enter name of input file "; ID$(IFILE); ":  ";
  195. 41020 LINE INPUT TNAME(IFILE)
  196. 41030 RETURN
  197. 42000 REM Stub:  gets user input of output target, sets resynch to 1
  198. 42010 TOUT="scrn:"
  199. 42020 PRINT "Send output to:"
  200. 42030 PRINT "  1  Screen"
  201. 42040 PRINT "  2  Printer"
  202. 42050 PRINT "  3  File or other device"
  203. 42060 LINE INPUT "    Enter choice:  "; TOUT
  204. 42070 IF TOUT="" THEN I=1 ELSE I=VAL(TOUT)
  205. 42080 IF I<1 OR I>3 THEN BEEP: GOTO 42060
  206. 42090 ON I GOTO 42100,42200,42300
  207. 42100 TOUT="SCRN:"
  208. 42120 GOTO 42500
  209. 42200 TOUT="LPT1:"
  210. 42220 GOTO 42500
  211. 42300 LINE INPUT "Enter file or device name:  "; TOUT
  212. 42500 RESYNCH=1
  213. 42510 RETURN
  214. 50000 REM The following defines and describes all program variables.
  215. 50010 MAXLINES=100: REM Maximum line indices for resynch attempt
  216. 50020 REM Above must be equal to the second dimension below.
  217. 50030 DIM T(2,100): REM Holds up to 100 out-of-synch lines per file
  218. 50040 DIM TNEXT(2): REM Holds current line for each file
  219. 50050 DIM COUNT(2): REM Line counter for each file
  220. 50060 DIM BOTTOM(2): REM Line number for T(x,1), when T in use.
  221. 50070 DIM PTR(2): REM Index into T(x,...)
  222. 50080 DIM LIMIT(2): REM Highest T(x,...) in use by input routine.
  223. 50090 DIM FIRST(2): REM Lowest T(x,...) in use by input routine.
  224. 50092 DIM LAST(2): REM Highest T(x,...) in use by resynch routine.
  225. 50100 I=0: J=0: REM General integer counters
  226. 50110 IFILE=0: REM Selects FILE 1 or 2, for input routine, etc
  227. 50112 JFILE=0: REM Resynch routine keeps this the opposite of IFILE
  228. 50120 DIM IGET(2): REM IGET(x) true when "input" from T(x)
  229. 50130 LFILE=3: REM File number for output
  230. 50140 DIM TNAME(2): REM Names of the input files
  231. 50150 TOUT="": REM Name of the output file or device
  232. 50152 T="": REM Used as temporary in user input routine.
  233. 50160 ISDIF=0: REM TRUE when differences have been found.
  234. 50170 ISSCREEN=0: REM TRUE when output is to SCRN:
  235. 50180 RESYNCH=0: REM Number of lines which must match for resynch
  236. 50190 DIM ID$(2): REM Array to identify input files
  237. 50200 ID$(1)="one": ID$(2)="two"
  238. 50210 TCONTROL=CHR$(165): REM The center dot character
  239. 50220 C=0: REM Character index for control char removal
  240. 50990 RETURN
  241.